<?php

namespace CrontabConsole\drivers;

use Yii;
use yii\helpers\BaseFileHelper;
use yii\base\BaseObject;
use Mmarica\DisplayTable;

/**
 * 任务文件存储
 */
class File extends BaseObject implements DriverInterface {
    public $crontabDataFile;
    
    /**
     * 任务列表
     */
    public $tasks = [];

    public function __construct($config = []) {
        parent::__construct($config);
    }

    /**
     * 初始化任务
     */
    public function init()
    {
        parent::init();

        $this->crontabDataFile = Yii::getAlias('@runtime/crontab') . '/crontab.data';
        if (is_file($this->crontabDataFile)) {
            return;
        }
        
        $this->installCrontab();
    }

    /**
     * 初始化任务
     */
    public function installCrontab() 
    {
        $objs = [];

        foreach($this->tasks as $id => $task) {
            $taskObj = Yii::createObject(array_merge(['class' => 'CrontabConsole\Task'], $task));
            $taskObj->calcNextRunDatetime();
            $taskObj->id = $id;
            $objs[] = $taskObj;
        }

        // 创建目录
        if (BaseFileHelper::createDirectory(Yii::getAlias('@runtime/crontab'))) {
            // 初始化任务
            return file_put_contents($this->crontabDataFile, serialize($objs));
        }

        throw new \Exception("createDirectory permission => " . Yii::getAlias('@runtime/crontab'), 1);
    }

    /**
     * 获取所有任务
     */
    public function getAllTasks() 
    {
        return unserialize(file_get_contents($this->crontabDataFile));
    }

    /**
     * 获取达到指定时间的任务
     * @return array $tasks [Task, Task....]
     */
    public function getRunTasks() 
    {
        $nowDatetime = date('Y-m-d H:i:s');
        $taskObjs = $this->getAllTasks();
        $runTasks = [];
        foreach ($taskObjs as $id => $task) {

            // 判断运行状态, 开关状态
            if ($task->status == 1 || $task->switch == 0) {
                continue;
            }

            if ($nowDatetime >= $task->next_rundate) {
                $runTasks[$id] = $task;
            }
        }

        return $runTasks;
    }

    public function add(\CrontabConsole\Task $task) 
    {

    }

    public function del($id) 
    {

    }

    /**
     * 更新任务
     */
    public function updateOne(\CrontabConsole\Task $task)
    {
        $taskObjs = unserialize(file_get_contents($this->crontabDataFile));
        foreach($taskObjs as $id => $obj) {
            if ($obj->id == $task->id) {
                $taskObjs[$task->id] = $task;
            }
        }
        return file_put_contents($this->crontabDataFile, serialize($taskObjs), LOCK_EX);
    }

    /**
     * 控制台打印任务状态
     */
    public function display() 
    {
        $tasks = $this->getAllTasks();

        $dataRows = [];

        $statusTextMap = [
            0 => '--',
            1 => 'RUNNING',
            2 => 'ERROR',
        ];

        foreach($tasks as $t) {

            $d = [
                $t->route,
                $t->crontab_str,
                $t->last_rundate,
                $t->next_rundate,
                $statusTextMap[$t->status],
                $t->count,
                $t->exectime,
            ];

            $dataRows[] = $d;
        }

        echo DisplayTable::create()
            ->headerRow(['route', 'crontab_str', 'last_rundate', 'next_rundate', 'status', 'exec_count', 'exec_time(s)'])
            ->dataRows($dataRows)
            ->toText()
            ->roundedBorder()
            ->generate();
    }

    /**
     * 重置任务
     */
    public function refresh() 
    {
        $this->installCrontab();
    }
    
}